/*
 * Copyright Radosław Smogura, 2012. All rights reserved.
 *
 * The content of this file is confidential and it is intelectual property
 * of copyright owners.
 * 
 *
 * $URL: http://reprap-ide.googlecode.com/svn/trunk/RepRapIDE/RepRapProject/src/main/java/eu/softper/reprap/generator/TriangleFanRemover.java $
 * $Id: TriangleFanRemover.java 3 2012-11-19 10:58:30Z mail@smogura.eu $
 * $Revision: 3 $
 */
package eu.softper.reprap.generator;

import java.util.*;

/**
 *
 * @author rsmogura
 */
public class TriangleFanRemover<T extends Number & Comparable<T>> {

    /**
     * Lines l1 and l2 must be connected in one point.
     */
    protected boolean checkIfLineConnected(SceneLine<T> l1, SceneLine<T> l2, Layer<T> l) {
        final DecimalVertex<T> point1, point2, point3;
        if (l1.getV1().equals(l2.getV1())) {
            point1 = l1.getV2();
            point2 = l2.getV2();
        } else if (l1.getV1().equals(l2.getV2())) {
            point1 = l1.getV2();
            point2 = l2.getV1();
        } else if (l1.getV2().equals(l2.getV1())) {
            point1 = l1.getV1();
            point2 = l2.getV2();
        } else if (l1.getV2().equals(l2.getV2())) {
            point1 = l1.getV1();
            point2 = l2.getV1();
        } else {
            throw new IllegalArgumentException("Passed line l1 and l2 must be connected in one point.");
        }
        
        Collection<SceneLine<T>> linesFrom1 = l.getLinesFromVertex().get(point1);
        
        /*
         * Check if set multiplication is not empty.
         */
        for (SceneLine<T> line : linesFrom1){
            if (line.getV1().equals(point2) || line.getV2().equals(point2))
                return true;
        }
        
        return false;
    }

    public void removeInnerLines(Layer<T> layer) {
        Set<SceneLine<T>> linesToRemove = new HashSet<SceneLine<T>>();
        
        for (Map.Entry<DecimalVertex<T>, Collection<SceneLine<T>>> e : layer.getLinesFromVertex().entrySet()) {
            /*
             * At least 3 lines must be outgoing from given point.
             */
            if (e.getValue().size() < 3) {
                continue;
            }

            for (SceneLine l : e.getValue()) {
                if (linesToRemove.contains(l))
                    continue;
                SceneLine l2 = null, l3 = null;
                for (SceneLine i2l : e.getValue()) {
                    if (i2l.equals(l) || i2l.equals(l2) || i2l.equals(l3) ) {
                        continue;
                    }

                    if (checkIfLineConnected(l, i2l, layer)) {
                        if (l2 == null) {
                            l2 = i2l;
                        } else {
                            l3 = i2l;
                            break;
                        }
                    }
                }

                if (l2 != null && l3 != null) {
                    linesToRemove.add(l);
                }
            }
        }
        
        for (SceneLine l : linesToRemove) {
            l.setLineType(SceneLineType.INNER);
        }
    }
}
